package org.amos.msg.platform.wx;

import cn.hutool.core.collection.CollUtil;
import com.google.common.base.Throwables;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import org.amos.core.basic.utils.JsonUtils;
import org.amos.msg.model.WxMpContentModel;
import org.amos.msg.params.PushMsgParam;
import org.amos.msg.platform.AbstractMsgPlatform;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Slf4j
public class WxMpMsgPlatform extends AbstractMsgPlatform<WxMpMsgConfig> {

    private WxMpService client;

    public WxMpMsgPlatform(String id, WxMpMsgConfig config) {
        super(id, config);
    }

    @Override
    protected void initClient() {
        WxMpDefaultConfigImpl configStorage = new WxMpDefaultConfigImpl();
        // 公众号appId
        configStorage.setAppId(config.getAppId());
        // 公众号appSecret
        configStorage.setSecret(config.getSecret());
        // 公众号Token
        configStorage.setToken(config.getToken());
        // 公众号EncodingAESKey
        configStorage.setAesKey(config.getAesKey());
        client = new WxMpServiceImpl();
        client.setWxMpConfigStorage(configStorage);
    }

    @Override
    public Boolean push(PushMsgParam param) {
        try {
            WxMpContentModel contentModel = (WxMpContentModel) param.getContentModel();
            List<WxMpTemplateMessage> messages = assembleReq(param.getReceiver(), contentModel);

            for (WxMpTemplateMessage message : messages) {
                try {
                    client.getTemplateMsgService().sendTemplateMsg(message);
                } catch (Exception e) {
                    log.info("OfficialAccountHandler#handler fail! param:{},e:{}", JsonUtils.objectToJson(param), Throwables.getStackTraceAsString(e));
                }
            }
            return Boolean.TRUE;
        } catch (Exception e) {
            log.error("OfficialAccountHandler#handler fail:{},params:{}", Throwables.getStackTraceAsString(e), JsonUtils.objectToJson(param));
        }
        return Boolean.FALSE;
    }

    /**
     * 组装发送模板信息参数
     */
    private List<WxMpTemplateMessage> assembleReq(Set<String> receiver, WxMpContentModel contentModel) {
        List<WxMpTemplateMessage> wxMpTemplateMessages = new ArrayList<>(receiver.size());
        for (String openId : receiver) {
            WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
                    .toUser(openId)
                    .templateId(contentModel.getTemplateId())
                    .url(contentModel.getUrl())
                    .data(getWxMpTemplateData(contentModel.getWxMpParam(), contentModel.getWxMpParamColor()))
                    .miniProgram(new WxMpTemplateMessage.MiniProgram(contentModel.getMiniProgramId(), contentModel.getPath(), false))
                    .build();
            wxMpTemplateMessages.add(templateMessage);
        }
        return wxMpTemplateMessages;
    }

    /**
     * 构建模板消息参数
     *
     * @return
     */
    private List<WxMpTemplateData> getWxMpTemplateData(Map<String, String> data, Map<String, String> color) {
        List<WxMpTemplateData> templateDataList = new ArrayList<>(data.size());
        try {
            if (CollUtil.isEmpty(color)) {
                data.forEach((k, v) -> templateDataList.add(new WxMpTemplateData(k, v)));
            } else {
                data.forEach((k, v) -> templateDataList.add(new WxMpTemplateData(k, v, color.get(k))));
            }
        } catch (Exception e) {
            log.error("[组装微信消息] 发生异常：", Throwables.getStackTraceAsString(e));
        }
        return templateDataList;
    }
}
